package com.dingnate.netty.client.demo;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;

public class HttpClient {
    EventLoopGroup workerGroup = new NioEventLoopGroup();

    public String send(String url, String msg, HttpMethod httpMethod, Map<String, String> headers) throws URISyntaxException, InterruptedException, UnsupportedEncodingException {
        URI uri = new URI(url);

        HttpClientInboundHandler httpClientInboundHandler = new HttpClientInboundHandler();
        Bootstrap b = new Bootstrap();
        b.group(workerGroup);
        b.channel(NioSocketChannel.class);
        b.option(ChannelOption.SO_KEEPALIVE, true);
        b.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
                ChannelPipeline p = ch.pipeline();
                p.addLast(new HttpClientCodec());
                p.addLast(new HttpContentDecompressor());
                p.addLast(new HttpObjectAggregator(1048576));
                p.addLast(httpClientInboundHandler);
            }
        });

        // Start the client.
        ChannelFuture f = b.connect(uri.getHost(), uri.getPort() == 0 ? 80 : uri.getPort()).sync();

        DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, httpMethod,
                uri.getRawQuery() == null ? uri.getRawPath() : String.format("%s?%s", uri.getRawPath(), uri.getRawQuery()), Unpooled.wrappedBuffer(msg.getBytes("UTF-8")));

        // 构建http请求
        HttpHeaders httpHeaders = request.headers();
        httpHeaders.set(HttpHeaderNames.HOST, uri.getHost());
        httpHeaders.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
        httpHeaders.set(HttpHeaderNames.CONTENT_LENGTH, request.content().readableBytes());
        //自定义header
        if (headers != null && headers.size() > 0) {
            for (Map.Entry<String, String> header : headers.entrySet()) {
                httpHeaders.set(header.getKey(), header.getValue());
            }
        }

        // 发送http请求
        f.channel().write(request);
        f.channel().flush();
        f.channel().closeFuture().sync();
        return httpClientInboundHandler.getResponse();
    }

}